#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: set sw=4 sts=4 et tw=80 :

import cookielib, urllib2, urllib
import re, os, sys, tempfile, mimetypes, traceback, shutil, getpass
from operator import itemgetter
from urllib2 import HTTPError, URLError
from BeautifulSoup import BeautifulSoup
from zipfile import ZipFile
try:
    from rarfile import RarFile, NotRarFile
except ImportError:
    print 'Necessário módulo: rarfile'
    sys.exit()


class FuncType:
    LOGIN = 'FUNC_LOGIN'
    LOGOUT = 'FUNC_LOGOUT'
    SEARCH = 'FUNC_SEARCH'
    DOWNLOAD = 'FUNC_DOWNLOAD'

class LoginOpt:
    DONT_STAY_LOGGED = '0'
    STAY_LOGGED = '1'

class SearchType:
    RELEASE = '1'
    MOVIE = '2'
    USER = '3' # Not supported

class SearchLang:
    PT_BR = '1'
    PT_PT = '10'
    EN = '2'
    ES = '3'
    OTHER = '100'
    ALL = '99'

class NetworkConn:

    def __init__(self, username, password, download_dir=None):
        if not download_dir:
            download_dir = tempfile.gettempdir()

        self.download_path = os.path.abspath(download_dir)
        self.base_url = 'http://legendas.tv'
        self.username = username
        self.password = password

        self.cookieJar = cookielib.CookieJar()
        self.opener= urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))
        urllib2.install_opener(self.opener)

    def login(self, login_opt=LoginOpt.DONT_STAY_LOGGED):
        '''LoginForm:
            txtLogin -> max_length(15)
            txtSenha -> max_length(15)
            chkLogin -> 0|1 (keep logged?)
        '''
        login_data = urllib.urlencode({'txtLogin':self.username,'txtSenha':self.password,'chkLogin':login_opt})
        request = urllib2.Request(self.base_url+'/login_verificar.php',login_data)
        try:
            self.response = urllib2.urlopen(request).read()
        except HTTPError, e:
            print e.code
        except URLError, e:
            print e.reason

    def logout(self):
        request = urllib2.Request(self.base_url+'/logoff.php')
        try:
            self.response = urllib2.urlopen(request)
        except HTTPError, e:
            print e.code
        except URLError, e:
            print e.reason

    def search(self, vsearch, vtype=SearchType.RELEASE, slang=SearchLang.PT_BR):
        search_dict = {'txtLegenda':vsearch,'selTipo':vtype,'int_idioma':slang}
        search_data = urllib.urlencode(search_dict)

        request = urllib2.Request(self.base_url+'/index.php?opcao=buscarlegenda',search_data)
        response = urllib2.urlopen(request)
        page = response.read()
        self.download_id, self.release = '', ''

        soup = BeautifulSoup(page)
        span_results = soup.find('td',{'id':'conteudodest'}).findAll('span')
        if span_results:
            opcoes = 0
            list_download_ids = []
            list_releases = {}
            best_download = 0
            for span in span_results:
                # há dois tipos de span na busca.
                #Este não contem o que nós gente queremos
                if span.attrs == [('class', 'brls')]:
                    continue
                td = span.find('td',{'class':'mais'})

                                #recupera o ID do download que tá no código javascript
                download_id_js = td.parent.parent.attrs[1][1]
                download_id = re.search('[a-z0-9]{32}',download_id_js).group(0)
                downloads = td.contents[5]

                if int(downloads) > best_download:
                    release = td.parent.parent.find('span',{'class':'brls'}).contents[0]
                    sub_name = td.contents[0].contents[0]
                    comentarios = td.contents[7]
                    avaliacao = td.contents[10]
                    equipe = td.parent.find('a').contents[0]
                    data = span.findAll('td')[2].contents[0]
                    best_download = int(downloads)
                    self.download_id = download_id
                    self.release = release

                list_download_ids.append(download_id)
                opcoes+=1
                #print 'Hash: '+download_id
                #print 'Opção: '+str(opcoes)
                #print 'Serie: '+sub_name
                #print 'Release: '+release
                #print 'Downloads: '+downloads
                #print 'Comentarios: '+comentarios
                #print 'Avaliacao: '+avaliacao
                #print 'Usuario: '+equipe
                #print 'Data: '+data
                #print '-------------------------------------'
            if self.download_id:
                return True

    def download(self):
        if self.download_id:
            url_request = self.base_url+'/info.php?d='+self.download_id+'&c=1'
            print 'Downloading release: ' + self.release 
            request =  urllib2.Request(url_request)
            response = urllib2.urlopen(request)
            legenda = response.read()

            self.filename = os.path.join(self.download_path, str(self.download_id))
            if response.info().get('Content-Type').__contains__('rar'):
                self.filename += '.rar'
            else:
                self.filename += '.zip'
            f = open(self.filename, 'w')
            f.write(legenda)
            f.close()
            print 'Subtitle downloaded with sucess!'
            return True

    def extract_sub(self, rls_name='', dirpath='', pref_type='.srt'):
        #filepath = os.path.split(self.filename)[0]
        if not dirpath:
            filepath = os.getcwd()
        else:
            filepath = dirpath

        mime, ret = mimetypes.guess_type(self.filename)        
        try:
            print 'Extracting compressed', 
            if mime == 'application/x-rar-compressed':
                print 'rar file...'
                archive = RarFile(self.filename)
            elif mime == 'application/zip':
                print 'zip file...'
                archive = ZipFile(self.filename)
        except:
            print 'Error opening file.'
            return False
        else:
            files = archive.namelist()
            srt_sub = []

            for filename in files:
                if re.search(rls_name, filename, re.I):
                    if filename.endswith('.srt'):
                        srt_sub.append(filename)
            
            if pref_type == '.srt' and len(srt_sub) > 0:
                for filename in srt_sub:
                    p_file = os.path.join(filepath, filename)
                    #f = open(p_file, 'w')
                    try:
                        archive.extractall(self.download_path)
                        from_subs = os.path.join(self.download_path, filename)
                        dest_subs = os.path.join(filepath, filename)
                        shutil.copy2(from_subs, dest_subs)
                        print 'Subtitle saved with sucess in %s!' % dest_subs
                    except Exception:
                        print 'print_exc():'
                        traceback.print_exc(file=sys.stdout)
                        print
                        print 'print_exc(1):'
                        traceback.print_exc(limit=1, file=sys.stdout)
                        return False
                    #f.close()
            else:
                print '...'
                return False
        

if __name__ == '__main__':
    not_valid = ['HDTV', 'XviD', 'X264', 'x264', 'Bluray', 'Unrated', 'DC', 'AC3', \
                 'DTS', 'Dual', 'VTV', 'DvdScr']
    video_format=['480i', '480p', '720i', '720p', '1080i', '1080p']
    rls_group = ['LOL', 'FQM', 'NoTV', 'CTU', 'IMMERSE', 'ZMG', 'CBGB', \
                 'AMIABLE', 'ViSiON', 'DIMENSION', 'TDF', 'MOMENTUM', 'FoV', \
                 'PROFILE', '2HD', 'BIA', 'VOMIT', 'lOVE', 'FEVER', 'P0W4', \
                 'C_P', 'FiHViD', 'FOX', '2Lions', 'RUBY', 'FXG', 'QcF', \
                 'T00NG0D', 'CHD', 'NLUPPER', 'LTRG', 'DUQA', 'CRYS', 'iLG', \
                 'SAPHiRE', 'REMAX', 'Rx']

	# Insert here your username and password if you dont want insert in input everytime
    username = ''
    password = ''

    # If variables above is empty, ask from keyboard
    if len(username) == 0:
        username = raw_input('Username: ')
        if len(password) == 0:
            password = getpass.getpass('Password: ')

    input_string = sys.argv[1:]
    search_string = input_string
    if os.path.isfile(input_string[0]):
        dirpath, search_string = os.path.split(input_string[0])

    # Removing some file extensions
    if len(input_string) == 1:
        search_string = re.split('\.|\-|\[|\]', search_string)
        if search_string[-1] in ['part']:
            search_string.pop()
        if search_string[-1] in ['avi', 'mkv', 'wmv']:
            search_string.pop()
            if not dirpath:
                file_abspath = os.path.abspath(input_string[0])
                dirpath = os.path.split(file_abspath)[0]
        rls_name = search_string[-1]
    else:
        search_string = input_string
        rls_name = ''
        for item in search_string:
            lt = [ match for match in rls_group if re.match(item, match, re.I)]
            if len(lt) > 0:
                rls_name = lt[0]
        dirpath = os.getcwd()

    # Removing empty strings
    search_string = [ st for st in search_string if st ]

    for item in not_valid:
        for idx, val in enumerate(search_string):
            if item == val:
                search_string.pop(idx)


    # Logging in Legendas.TV
    conn = NetworkConn(username, password)
    conn.login()

    if conn.response.__contains__('Dados incorretos'):
        print 'Ooops wrong info...'
        sys.exit()
    else:
        print '-------------------'
        print 'Logged with sucess!'
    print '------------------'
    print 'Searching for: ' + " ".join(search_string)
    print '------------------'
    if conn.search(" ".join(search_string)):
        if conn.download():
            conn.extract_sub(rls_name, dirpath)
    elif len(search_string) > 1:
        format_found = False
        for index, value in enumerate(search_string):
            if value in video_format:
                search_string.pop(index)
            elif search_string[index] == search_string[-1]:
                search_string.pop()
        print 'Not found. New search...'
        print '------------------'
        print 'Searching for: ' + " ".join(search_string)
        print '------------------'
        conn.search(" ".join(search_string))
        if conn.download():
            conn.extract_sub(rls_name, dirpath)
        else:
            print 'Subtitle not found...'
    conn.logout()
